<template lang="pug">
  .data-table-wrapper(
    ref="data-table-wrapper"
    :style="tableWrapperStyle"
    v-resize:debounce.100="renderWidth")
    v-table.data-table(
      v-if="tableWrapperWidth"
      :tableStyle="tableStyle")
      ul.data-table-header(slot="header",name="header",:style="headerStyle")
        v-tr
          v-th(
            v-for="(columnName,index) in tableList"
            :key="columnName"
            :columnName="columnName"
            :column="columns[columnName]"
            :columnStyle="columnName | columnStyle(columnsWidth, columns)"
            :style="isCenterStyle"
            :orderBy="orderBy"
            @changeOrderBy="changeOrderBy")
          v-th(
            v-if="operationList && operationList.length>0"
            :column="{label:'操作'}"
            :columnStyle="operationWidth | operationStyle")
      slot(v-if="!isLoading && tableData.length > 0")
        v-tbody.data-table-content
          template(v-if="isTree")
            tree-table-record(
              v-for="(data,index) in tableData"
              :key="index"
              :recordIndex="[index]"
              :tableList="tableList"
              :mainColumn="mainColumn"
              :columns="columns"
              :columnsWidth="columnsWidth"
              :operationList="operationList"
              :operationWidth="operationWidth"
              :treeExpands="treeExpands"
              :style="recordStyle"
              :data="data"
              :hoverRecord="hoverRecord"
              @changeTreeExpands="changeTreeExpands"
              @changeHoverRecord="changeHoverRecord")
          template(v-else)
            data-table-record(
              v-for="(data,index) in tableData"
              v-on="$listeners"
              :key="data.id"
              :recordIndex="[index]"
              :tableList="tableList"
              :columns="columns"
              :columnsWidth="columnsWidth"
              :operationList="operationList"
              :operationWidth="operationWidth"
              :style="[recordStyle, isCenterStyle]"
              :data="data"
              :hoverRecord="hoverRecord"
              @changeHoverRecord="changeHoverRecord")
            data-table-record(
              v-if="isCount"
              :recordIndex="[index]"
              :tableList="tableList"
              :columns="columns"
              :columnsWidth="columnsWidth"
              :operationList="operationList"
              :operationWidth="operationWidth"
              :style="recordStyle"
              :data="countData"
              :hoverRecord="hoverRecord"
              @changeHoverRecord="changeHoverRecord")
    slot(v-if="isLoading && hasLoading")
      .noData
        span.loading-wrapper
          span.loading
        | 加载中...
    slot(v-if="!isLoading && hasLoading && tableData.length===0")
      .noData 暂时没有数据
</template>

<script>
import IScroll from 'iscroll/build/iscroll-probe.js'
import resize from 'vue-resize-directive'

import { sumBy, mapValues } from 'lodash'

import DataTableRecord from './DataTableRecord'
import TreeTableRecord from './TreeTableRecord'
import VTable from '@/components/VTable'
import VThead from '@/components/VTable/VThead'
import VTbody from '@/components/VTable/VTbody'
import VTr from '@/components/VTable/VTr'
import VTh from '@/components/VTable/VTh'
import VTd from '@/components/VTable/VTd'

export default {
  name: 'data-table-main',
  components: {
    DataTableRecord,
    TreeTableRecord,
    VTable,
    VThead,
    VTbody,
    VTr,
    VTh,
    VTd
  },
  props: {
    x: Number,
    y: Number,
    tableName: {
      type: String,
      default: ''
    },
    cid: {
      type: String,
      default: 'id'
    }, /* 页面对话框标题 */
    pid: {
      type: String,
      default: 'pid'
    }, /* 页面对话框标题 */
    columns: {
      type: Object,
      default: () => {
        return {}
      }
    },
    mainColumn: {
      type: String,
      default: ''
    },
    isCount: {
      type: Boolean,
      default: false
    },
    isScroll: {
      type: Boolean,
      default: false
    },
    hasLoading: {
      type: Boolean,
      default: false
    },
    isLoading: {
      type: Boolean,
      default: false
    },
    operationList: {
      type: Array,
      default: () => []
    },
    operationWidth: {
      type: Number,
      default: 200
    },
    clientHeight: {
      type: Number
    },
    tableWrapperWidth: {
      type: Number,
      default: 0
    },
    fullTableWidth: {
      type: Boolean,
      default: false
    },
    tableList: {
      type: Array,
      default: () => []
    },
    isTree: {
      type: Boolean,
      default: false
    },
    orderBy: {
      type: Array,
      default: () => []
    },
    tableData: {
      type: Array,
      default: () => []
    },
    isExpand: Function,
    treeExpands: {
      type: Array,
      default: () => []
    },
    hoverRecord: {
      type: String | Number
    },
    isCenter: { // 是否居中
      type: Boolean,
      default: true
    }
  },
  directives: {
    resize
  },
  data () {
    return {
      columnsList: mapValues(this.columns, item => {
        return {
          ...item,
          width: item.width || 200
        }
      }),
      isOutsideTbody: true
    }
  },
  computed: {
    isCenterStyle () {
      return this.isCenter ? {'text-align': 'center'} : ''
    },
    countData () {
      let countData = {}
      countData[this.tableList[0]] = '合计'
      this.tableList.map(item => {
        if (this.columns[item].isCount) {
          countData[item] = sumBy(this.tableData, item)
        }
      })
      return countData
    },
    tableWidth () {
      const operationWidth = this.operationList && this.operationList.length > 0 ? this.operationWidth : 0
      return this.columnWidth + operationWidth
    },
    columnWidth () {
      return this.tableList.reduce((acc, item) => {
        const itemWidth = this.columns[item].width || 200
        return acc + itemWidth
      }, 0)
    }, // 所有列的宽度
    redundancyWidth () {
      const redundancyWidth = this.tableWrapperWidth - this.tableWidth
      return redundancyWidth > 0 ? redundancyWidth : 0
    }, // 表格列冗余宽度
    recordStyle () {
      return {
        width: this.tableWidth + this.redundancyWidth + 'px'
      }
    },
    tableStyle () {
      let tableStyle = {}
      if (!this.isScroll) {
        if (this.x || this.y) {
          tableStyle['transform'] = `translate(${this.x || 0}px,${this.y || 0}px)`
        }
      }
      return {
        ...this.recordStyle,
        ...tableStyle
      }
    }, // 计算表格定位，用于同步悬浮层定位
    headerStyle () {
      let headerStyle = {}
      if (this.y) {
        headerStyle['transform'] = `translate(0px,${-this.y || 0}px)`
      }
      return headerStyle
    },
    tableWrapperStyle () {
      return {
        width: this.fullTableWidth ? '100%' : this.tableWrapperWidth + 'px'
      }
    },
    columnsWidth () {
      const { tableList, columnsList, redundancyWidth } = this
      const simple = Math.floor(redundancyWidth / tableList.length)
      const remainder = redundancyWidth - tableList.length * simple
      let columnsWidth = {}
      tableList.map((item, index) => {
        const normal = columnsList[item].width + simple
        columnsWidth[item] = index === (tableList.length - 1) ? normal + remainder : normal
      })
      return columnsWidth
    }
  },
  watch: {
    clientHeight () {
      if (this.tableScroll) {
        this.updatePosition()
      }
    }
  },
  filters: {
    columnStyle (columnName, columnsWidth, columns) {
      let style = {
        width: columnsWidth[columnName] + 'px',
        ...columns[columnName].style
      }
      return style
    },
    operationStyle (width) {
      return {
        width: width + 'px'
      }
    }
  },
  updated () {
    if (this.isScroll) {
      if (this.tableScroll) {
        this.tableScroll.refresh()
      } else {
        this.initScroll()
      }
    }
  },
  methods: {
    renderWidth () {
      this.tableWrapperWidth = this.tableWrapperWidth ? this.tableWrapperWidth : this.$refs['datatables-wrapper'].tableWrapperWidth + 2
    },
    initScroll () {
      this.tableScroll = new IScroll(this.$refs['data-table-wrapper'], {
        scrollX: true,
        scrollY: true,
        freeScroll: true,
        scrollbars: true,
        // scrollbars: 'custom',
        mouseWheel: true,
        interactiveScrollbars: true,
        probeType: 3,
        disablePointer: true,
        shrinkScrollbars: 'scale'
      })
      this.tableScroll.on('scroll', this.updatePosition)
    },
    updatePosition () {
      this.tableScroll.refresh()
      this.$emit('updatePosition', this.tableScroll.x, this.tableScroll.y)
    },
    changeOrderBy (data) {
      this.$emit('changeOrderBy', data)
    },
    changeTreeExpands (data) {
      this.$emit('changeTreeExpands', data)
    },
    changeHoverRecord (index) {
      this.$emit('changeHoverRecord', index)
    }
  }
}
</script>

<style scoped lang="sass">
.loading
  height: 400px
.data-table-wrapper
  background: #fff
  overflow: hidden
.data-table
  display: flex
  flex-direction: column
  flex: 1
.data-table-header
  z-index: 1
.data-table-content
  display: flex
  flex: 1
  flex-direction: column
  box-shadow: 0px 0px 1px #999
.noData
  position: absolute
  top: 50%
  left: 50%
  transform: translate(-50%, -50%)
  text-align: center
  font-size: 18px
  /* Styled scrollbars */
.iScrollHorizontalScrollbar
  position: absolute
  z-index: 9999
  height: 16px
  left: 2px
  right: 2px
  bottom: 2px
  overflow: hidden
.iScrollHorizontalScrollbar.iScrollBothScrollbars
  right: 18px
.iScrollVerticalScrollbar
  position: absolute
  z-index: 9999
  width: 16px
  bottom: 2px
  top: 2px
  right: 2px
  overflow: hidden
.iScrollVerticalScrollbar.iScrollBothScrollbars
  bottom: 18px
.iScrollIndicator
  position: absolute
  background: #cc3f6e
  border-width: 1px
  border-style: solid
  border-color: #EB97B4 #7C2845 #7C2845 #EB97B4
  border-radius: 8px
.iScrollHorizontalScrollbar .iScrollIndicator
  height: 100%
  background: -moz-linear-gradient(left,  #cc3f6e 0%, #93004e 100%)
  background: -webkit-linear-gradient(left,  #cc3f6e 0%,#93004e 100%)
  background: -o-linear-gradient(left,  #cc3f6e 0%,#93004e 100%)
  background: -ms-linear-gradient(left,  #cc3f6e 0%,#93004e 100%)
  background: linear-gradient(to right,  #cc3f6e 0%,#93004e 100%)
.iScrollVerticalScrollbar .iScrollIndicator
  width: 100%
  background: -moz-linear-gradient(top, #cc3f6e 0%, #93004e 100%)
  background: -webkit-linear-gradient(top,  #cc3f6e 0%,#93004e 100%)
  background: -o-linear-gradient(top, #cc3f6e 0%,#93004e 100%)
  background: -ms-linear-gradient(top, #cc3f6e 0%,#93004e 100%)
  background: linear-gradient(to bottom,  #cc3f6e 0%,#93004e 100%)
/* end */
</style>
